package com.webvihar.access2db.activities;

import java.util.ArrayList;
import java.util.List;

import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TextView;

import com.webvihar.access2db.R;
import com.webvihar.access2db.asynctasks.A2DbAsyncWebRequestTask;
import com.webvihar.access2db.builders.RunQueryBuilder;
import com.webvihar.access2db.builders.RunShowQueryBuilder;
import com.webvihar.access2db.model.Header;
import com.webvihar.access2db.model.QueryResult;
import com.webvihar.access2db.model.ShowQueryResult;
import com.webvihar.access2db.model.Table;
import com.webvihar.access2db.model.TableField;
import com.webvihar.access2db.restapi.A2DbRunQueryRequest;
import com.webvihar.access2db.restapi.A2DbRunShowQueryRequest;
import com.webvihar.access2db.restapi.A2DbWebResult;
import com.webvihar.access2db.utils.PreferencesManager;
import com.webvihar.common.utils.Logger;
import com.webvihar.common.utils.Validation;

public class AddEditDeleteTableActivity extends BaseActivity implements OnClickListener{

	public static List<TableField> currentTableFields;
	public static List<TableField> tableFields;
	private TextView titleTxt;
	private ImageButton titleActionButton;
	private EditText tableNameTxt;
	private Button addColumnBtn;
	private Button cancelBtn;
	private Button saveBtn;
	private Button deleteBtn;
	private LinearLayout addEditLayout;
	private LinearLayout deleteLayout;
	private TableLayout fieldsLayout;
	private String mode;
	private String tableName;

	public static final String TABLE_MANAGEMENT_TYPE_ADD = "Add";
	public static final String TABLE_MANAGEMENT_TYPE_EDIT = "Edit";
	public static final String TABLE_MANAGEMENT_TYPE_DELETE = "Delete";


	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		overridePendingTransition(R.anim.slide_in_right, R.anim.slide_out_left);
		setContentView(R.layout.add_edit_delete_table);
		tableFields = null;
		setMode();
		setTitleBar();
		initUI();
		updateUI();
		setListeners();
		if(!mode.equalsIgnoreCase(TABLE_MANAGEMENT_TYPE_ADD)) {
			startTableSchemaRequestProcess(getQueryBuilder().getTableDescriptionQuery(tableName));
		}
	}

	private void setMode() {
		Bundle bundle = getIntent().getExtras();
		mode = bundle.getString(KEY_TABLE_MANAGEMENT_NAVIGATION_MODE);
		tableName = (!mode.equalsIgnoreCase(TABLE_MANAGEMENT_TYPE_ADD)) ? bundle.getString(KEY_TABLE_NAME) : tableName;
		if(mode.equalsIgnoreCase(TABLE_MANAGEMENT_TYPE_EDIT) || mode.equalsIgnoreCase(TABLE_MANAGEMENT_TYPE_DELETE)) {
			currentTableFields = new ArrayList<TableField>();
		}
	}

	private void updateUI() {
		if(mode.equalsIgnoreCase(TABLE_MANAGEMENT_TYPE_ADD) || mode.equalsIgnoreCase(TABLE_MANAGEMENT_TYPE_EDIT)) {
			hideView(addEditLayout, false);
			hideView(deleteLayout, true);
		} else if(mode.equalsIgnoreCase(TABLE_MANAGEMENT_TYPE_DELETE) ) {
			hideView(addEditLayout, true);
			hideView(deleteLayout, false);
		}
	}

	@Override
	protected void onResume() {
		super.onResume();
		initTableFieldsList();
	}

	public void setTitleBar() {
		titleTxt = (TextView) findViewById(R.id.title_txt);
		if(mode.equalsIgnoreCase(TABLE_MANAGEMENT_TYPE_ADD)) {
			titleTxt.setText(getString(R.string.add_table_txt));
		} else if(mode.equalsIgnoreCase(TABLE_MANAGEMENT_TYPE_EDIT)) {
			titleTxt.setText(getString(R.string.edit_table_txt));
		} else if(mode.equalsIgnoreCase(TABLE_MANAGEMENT_TYPE_DELETE)) {
			titleTxt.setText(getString(R.string.delete_table_txt));
		} 
		titleActionButton = (ImageButton) findViewById(R.id.title_action_image_btn);
		titleActionButton.setVisibility(View.GONE);
	}

	private void initUI() {
		tableNameTxt = (EditText)findViewById(R.id.add_edit_delete_table_table_name_et);
		addColumnBtn = (Button)findViewById(R.id.add_edit_delete_table_add_coloumn_btn);
		cancelBtn = (Button)findViewById(R.id.add_edit_delete_table_cancel_btn);
		saveBtn = (Button)findViewById(R.id.add_edit_delete_table_save_table_btn);
		deleteBtn = (Button)findViewById(R.id.add_edit_delete_table_delete_table_btn);
		fieldsLayout = (TableLayout)findViewById(R.id.add_edit_delete_table_fields_tl);
		addEditLayout = (LinearLayout) findViewById(R.id.add_edit_delete_table_add_edit_layout);
		deleteLayout = (LinearLayout) findViewById(R.id.add_edit_delete_table_delete_layout);
	}

	private void setListeners() {
		addColumnBtn.setOnClickListener(this);
		cancelBtn.setOnClickListener(this);
		saveBtn.setOnClickListener(this);
		deleteBtn.setOnClickListener(this);
	}

	// Load table schema into tableFields
	private void loadTableSchema(Table table) {
		tableNameTxt.setText(tableName);
		for(int i=0; i<table.data.length; i++) {
			String fieldName = null;
			String type = null;
			String length = null;
			boolean zerofill = false;
			boolean unsigned = false;
			boolean allownull = false;
			String defaultValue = null;
			String collation = null;
			String comment = null;
			String[] tableRecord = table.data[i];
			for(int j=0; j<table.headers.length; j++) {
				Header header = table.headers[j];
				if(header.title.equalsIgnoreCase("Field")) {
					fieldName = tableRecord[j];
				} else if(header.title.equalsIgnoreCase("Type")) {
					String[] properties = tableRecord[j].split(" ");
					for(int p=0; p<properties.length; p++) {
						if(p == 0) {
							String property = properties[p];
							if(property.contains("(") && property.contains(")")) {
								type = property.substring(0, property.indexOf("("));
								length = property.substring(property.indexOf("(")+1, property.indexOf(")"));
							} else {
								type = property;
							}

						} else {
							zerofill = (properties[p].equalsIgnoreCase("unsigned")) ? true : zerofill;
							unsigned = (properties[p].equalsIgnoreCase("unsigned")) ? true : unsigned;
							allownull = (properties[p].equalsIgnoreCase("unsigned")) ? true : allownull;
						}
					}
				} else if(header.title.equalsIgnoreCase("Null")) {
					allownull = tableRecord[j].equalsIgnoreCase("YES") ? true : false;
				} else if(header.title.equalsIgnoreCase("Key")) {
					// TODO: will be used when primary/foreign keys are implemented
				} else if(header.title.equalsIgnoreCase("Default")) {
					defaultValue = tableRecord[j];
				} else if(header.title.equalsIgnoreCase("Extra")) {
					// TODO: will be used when Extras functionality is implemented
				}
			}
			// Logger.logInfo(Logger.LOG_TAG, fieldName+"\n"+length+"\n"+type+"\n"+zerofill+"\n"+unsigned+"\n"+allownull+"\n"+defaultValue+"\n"+collation+"\n"+comment);
			currentTableFields.add(new TableField(fieldName, type, length, zerofill, unsigned, allownull, defaultValue, collation, comment));
			tableFields.add(new TableField(fieldName, type, length, zerofill, unsigned, allownull, defaultValue, collation, comment));
		}
	}

	private void initTableFieldsList() {
		if(tableFields == null) {
			tableFields = new ArrayList<TableField>();
		} else {
			if(fieldsLayout.getChildCount() > 1) {
				fieldsLayout.removeViews(1, fieldsLayout.getChildCount()-1);
			}
			TableRow row;
			for(int i=0; i<tableFields.size(); i++) {
				final int tableFieldIndex = i;
				final TableField field = tableFields.get(i);

				row = new TableRow(this);
				row.setBackgroundColor(Color.GRAY);
				row.setPadding(2, 2, 2, 2);

				// Add Field Name
				row.addView(getTextView((field.fieldName != null) ? field.fieldName : "Null")); 
				//Add Type
				row.addView(getTextView((field.type != null) ? field.type : "Null")); 
				//Add length
				row.addView(getTextView((field.length != null) ? field.length : "Null")); 
				//Add Unsigned
				row.addView(getTextView(field.unsigned + "")); 
				//Add zero fill
				row.addView(getTextView(field.zerofill + "")); 
				//Add allow null
				row.addView(getTextView(field.allownull + "")); 
				//Add Default value
				row.addView(getTextView((field.defaultValue != null) ? field.defaultValue : "Null")); 
				//Add Collation
				row.addView(getTextView((field.collation != null) ? field.collation : "Null"));
				//Add comment
				row.addView(getTextView((field.comment != null) ? field.comment : "Null"));

				row.setOnClickListener(new OnClickListener() {
					@Override
					public void onClick(View v) {
						Intent intent = new Intent(AddEditDeleteTableActivity.this, AddEditDeleteTableFieldActivity.class);
						intent.putExtra(KEY_TABLE_FIELD_INDEX, tableFieldIndex+"");
						startActivity(intent);
					}
				});
				fieldsLayout.addView(row);
			}
		}
	}

	private TextView getTextView(String text) {
		return getTableDataTextView(this, text);
	}

	@Override
	public void onClick(View v) {
		if(v == addColumnBtn) {
			processData();
		} else if(v == cancelBtn) {
			AddEditDeleteTableActivity.this.finish();
		} else if(v == saveBtn) {
			if(mode.equalsIgnoreCase(TABLE_MANAGEMENT_TYPE_ADD)) {
				// TODO: update comment in query
				startDatabaseRequestProcess(getQueryBuilder().getCreateTableQuery(tableNameTxt.getText().toString(), "comment", tableFields));
			} else if(mode.equalsIgnoreCase(TABLE_MANAGEMENT_TYPE_EDIT)) {
				String query = getQueryBuilder().getEditTableQuery(tableName, tableNameTxt.getText().toString(), currentTableFields, tableFields);
				Logger.logInfo(Logger.LOG_TAG, query);
				startDatabaseRequestProcess(query);
			}
		} else if(v == deleteBtn) {
			startDatabaseRequestProcess(getQueryBuilder().getDeleteTableQuery(tableName));
		}
	}

	private void processData() {
		String tableName = tableNameTxt.getText().toString();
		if(isDataValid(tableName)) {
			Intent intent = new Intent(AddEditDeleteTableActivity.this, AddEditDeleteTableFieldActivity.class);
			intent.putExtra(KEY_TABLE_FIELD_INDEX, "-1");
			startActivity(intent); 
		}
	}

	private boolean isDataValid(String tableName) {
		if(!Validation.isString(tableName)) {
			showToast(getResources().getString(R.string.prompt_table_name_txt));
			return false;
		}
		return true;
	}
	public void startTableSchemaRequestProcess(String query) {
		A2DbRunShowQueryRequest request = new A2DbRunShowQueryRequest();
		request.encoded = true;
		request.host = 	PreferencesManager.getString(getApplicationContext(), PREF_SESSION_HOST);
		request.port =  PreferencesManager.getString(getApplicationContext(), PREF_SESSION_PORT);
		request.username = PreferencesManager.getString(getApplicationContext(), PREF_SESSION_USERNAME);
		request.password = PreferencesManager.getString(getApplicationContext(), PREF_SESSION_PASSWORD);
		request.dbname = PreferencesManager.getString(getApplicationContext(), PREF_SESSION_DBNAME);
		request.query = query;
		request.requestDelegate = new RunShowQueryBuilder();
		new A2DbAsyncWebRequestTask(true, getApplicationContext(), runShowQueryRequestHandler, getProgressDialog()).execute(request);
	}

	public void startDatabaseRequestProcess(String query) {
		A2DbRunQueryRequest request = new A2DbRunQueryRequest();
		request.encoded = true;
		request.host = 	PreferencesManager.getString(getApplicationContext(), PREF_SESSION_HOST);
		request.port =  PreferencesManager.getString(getApplicationContext(), PREF_SESSION_PORT);
		request.username = PreferencesManager.getString(getApplicationContext(), PREF_SESSION_USERNAME);
		request.password = PreferencesManager.getString(getApplicationContext(), PREF_SESSION_PASSWORD);
		request.dbname = PreferencesManager.getString(getApplicationContext(), PREF_SESSION_DBNAME);
		request.query = query;
		request.requestDelegate = new RunQueryBuilder();
		new A2DbAsyncWebRequestTask(true, getApplicationContext(), runQueryRequestHandler, getProgressDialog()).execute(request);
	}

	private Handler runShowQueryRequestHandler = new Handler() {
		@SuppressWarnings("unchecked")
		@Override
		public void handleMessage(Message msg) {
			super.handleMessage(msg);
			A2DbWebResult<ShowQueryResult> response = (A2DbWebResult<ShowQueryResult>) msg.obj;
			if(response == null) {
				showToast("Response is null");
				AddEditDeleteTableActivity.this.finish();
			} else if(response.entity == null) {
				showToast("Server not found...");
				AddEditDeleteTableActivity.this.finish();
			} else if(response.entity.result == null){
				showToast(response.entity.error+"");
				AddEditDeleteTableActivity.this.finish();
			} else {
				loadTableSchema(response.entity.result);
				initTableFieldsList();
			}
		}
	};
	
	private Handler runQueryRequestHandler = new Handler() {
		@SuppressWarnings("unchecked")
		@Override
		public void handleMessage(Message msg) { 
			super.handleMessage(msg);
			A2DbWebResult<QueryResult> response = (A2DbWebResult<QueryResult>) msg.obj;
			if(response == null) {
				showToast("Response is null");
				AddEditDeleteTableActivity.this.finish();
			} else if(response.entity == null) {
				showToast("Server not found...");
				AddEditDeleteTableActivity.this.finish();
			} else if(response.entity.result == null){
				showToast(response.entity.error+"");
				AddEditDeleteTableActivity.this.finish();
			} else {
				showToast(response.entity.result);
				AddEditDeleteTableActivity.this.finish();
			}
		}
	};
}
